#include "event_loop.h"


#define TRANS_TO_EV_MASK(mask) \
    (((mask) & EventLoop::READ ? EV_READ : 0) | ((mask) & EventLoop::WRITE ? EV_WRITE : 0))

#define TRANS_FROM_EV_MASK(mask) \
    (((mask) & EV_READ ? EventLoop::READ : 0) | ((mask) & EV_WRITE ? EventLoop::WRITE : 0))

    
namespace xrtc{

// 事件回调函数
static void generic_io_cb(struct ev_loop* /*loop*/, struct ev_io* io, int events) {
    IOWatcher* watcher = (IOWatcher*)(io->data);
    watcher->m_cb(watcher->m_el, watcher, io->fd, TRANS_FROM_EV_MASK(events), watcher->m_data);
}

static void generic_timer_cb(struct ev_loop* /*loop*/, struct ev_timer* timer, int /*events*/) {
    TimerWatcher* watcher = (TimerWatcher*)(timer->data);   
    watcher->m_cb(watcher->m_el, watcher, watcher->m_data);
}

EventLoop::EventLoop(void* owner) : m_owner(owner), m_loop(ev_loop_new(EVFLAG_AUTO)) {

}

EventLoop::~EventLoop() {

}

void EventLoop::start() {
    ev_run(m_loop);
}

void EventLoop::stop() {
    ev_break(m_loop, EVBREAK_ALL);
}

// 创建IO事件
IOWatcher *EventLoop::createIOEvent(io_cb_t cb, void *data) {
    IOWatcher* w = new IOWatcher(this, cb, data);
    ev_init(&(w->m_io), generic_io_cb);
    return w;
}

// 启动并添加事件
void EventLoop::startIOEvent(IOWatcher *w, int fd, int mask) {
    struct ev_io* io = &(w->m_io);
    // 事件循环已启动
    if (ev_is_active(io)) {
        int active_events = TRANS_FROM_EV_MASK(io->events);
        // 合并事件
        int events = active_events | mask;
        // 事件未发生任何变化
        if (events == active_events) {
            return;
        }
        // 添加事件
        events = TRANS_TO_EV_MASK(events);
        // 事件循环已启动，先停止再启动
        ev_io_stop(m_loop, io);
        ev_io_set(io, fd, events);
        ev_io_start(m_loop, io);
    } else {
        // 第一次添加事件，并启动事件循环
        int events = TRANS_TO_EV_MASK(mask);
        ev_io_set(io, fd, events);
        ev_io_start(m_loop, io);
    }
}

// 停止并删除事件
void EventLoop::stopIOEvent(IOWatcher *w, int fd, int mask) {
    struct ev_io* io = &(w->m_io);
    int active_events = TRANS_FROM_EV_MASK(io->events);
    // 移除事件
    int events = active_events & (~mask);
    // 未添加事件
    if (events == active_events) {
        return;
    }
    events = TRANS_TO_EV_MASK(events);
    ev_io_stop(m_loop, io);
    
    // 移除对应事件之后，事件循环中还有事件
    if (events != EV_NONE) {
        ev_io_set(io, fd, events);
        ev_io_start(m_loop, io);
    }
}

// 关闭并删除事件
void EventLoop::deleteIOEvent(IOWatcher *w) {
    struct ev_io* io = &(w->m_io);
    ev_io_stop(m_loop, io);
    delete w;
}

// 创建定时器
TimerWatcher *EventLoop::createTimer(time_cb_t cb, void *data, bool need_repeat) {
    TimerWatcher* watcher = new TimerWatcher(this, cb, data, need_repeat);
    ev_init(&(watcher->m_timer), generic_timer_cb);
    return watcher;
}

void EventLoop::startTimer(TimerWatcher *w, unsigned int usec) {
    struct ev_timer* timer = &(w->m_timer);
    float sec = float(usec) / 1000000.0f;
    if (!w->m_repeat) {
        // 定时器不重复执行
        ev_timer_stop(m_loop, timer);
        ev_timer_set(timer, sec, 0.0);
        ev_timer_start(m_loop, timer);
    } else {
        // 定时器重复执行
        timer->repeat = sec;
        ev_timer_again(m_loop, timer);
    }
}

void EventLoop::stopTimer(TimerWatcher *w) {
    struct ev_timer* timer = &(w->m_timer);
    ev_timer_stop(m_loop, timer);
}

void EventLoop::deleteTimer(TimerWatcher *w) {
    stopTimer(w);
    delete w;
}

}
